package org.jason.interaction.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.jason.common.constants.ArticleConstants;
import org.jason.common.constants.ArticleInteractionConstants;
import org.jason.feign.user.UserClient;
import org.jason.interaction.mq.producer.ArticleProducer;
import org.jason.interaction.repository.ArticleCommentRepository;
import org.jason.interaction.service.ICommentService;
import org.jason.model.common.dtos.ResponseResult;
import org.jason.model.common.enums.HttpCodeEnum;
import org.jason.model.interaction.dtos.ArticleInteractionDto;
import org.jason.model.interaction.dtos.DeleteCommentDto;
import org.jason.model.interaction.dtos.LoadCommentsDto;
import org.jason.model.interaction.dtos.SendCommentDto;
import org.jason.model.interaction.es.ArticleComment;
import org.jason.model.user.pojos.CuUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Transactional
public class CommentServiceImpl implements ICommentService {

    @Autowired
    private ArticleCommentRepository articleCommentRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticTemplate;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ArticleProducer articleProducer;

    /**
     * 加载文章评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ArticleComment>> loadComments(LoadCommentsDto dto) {
        List<ArticleComment> comments;
        if (dto.getType().equals(1)) {
            //根据文章id查询评论然后按评论时间倒序
            TermQueryBuilder builder = QueryBuilders.termQuery("articleId", dto.getArticleId());
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(builder)
                    .withSort(SortBuilders.fieldSort("commentTime").order(SortOrder.DESC))
                    .build();
            SearchHits<ArticleComment> searchHits = elasticTemplate.search(query, ArticleComment.class);
            comments = searchHits.map(SearchHit::getContent).toList();
        } else {
            //根据文章id查询评论然后按点赞数倒序
            TermQueryBuilder builder = QueryBuilders.termQuery("articleId", dto.getArticleId());
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(builder)
                    .withSort(SortBuilders.fieldSort("likes").order(SortOrder.DESC))
                    .build();
            SearchHits<ArticleComment> searchHits = elasticTemplate.search(query, ArticleComment.class);
            comments = searchHits.map(SearchHit::getContent).toList();
        }
        return new ResponseResult<>(HttpCodeEnum.SUCCESS, comments);
    }

    /**
     * 删除评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult delComment(DeleteCommentDto dto) {
        int userId = StpUtil.getLoginIdAsInt();
        articleCommentRepository.findById(dto.getCommentId()).ifPresent(comment -> {
            if (comment.getUserId() == userId) {
                articleCommentRepository.deleteById(dto.getCommentId());
                //发送删除评论到mq
                ArticleInteractionDto dto1 = new ArticleInteractionDto();
                dto1.setArticleId(dto.getArticleId());
                dto1.setType(ArticleInteractionConstants.COMMENT);
                articleProducer.cancelArticleInteraction(dto1);
            }
        });
        return ResponseResult.get(HttpCodeEnum.SUCCESS);
    }

    /**
     * 发表评论
     *
     * @param dto 评论数据
     */
    @Override
    public void sendComment(SendCommentDto dto) {
        Integer userId = dto.getUserId();
        CuUser user = userClient.getUserInfo(userId).getData();
        ArticleComment comment = new ArticleComment()
                .setUserId(userId)
                .setNickname(user.getNickname())
                .setArticleId(dto.getArticleId())
                .setComment(dto.getComment())
                .setLikes(0)
                .setCommentTime(LocalDateTime.now());
        articleCommentRepository.save(comment);
        //发送添加评论到mq
        ArticleInteractionDto dto1 = new ArticleInteractionDto();
        dto1.setArticleId(dto.getArticleId());
        dto1.setType(ArticleInteractionConstants.COMMENT);
        articleProducer.ArticleInteraction(dto1);
    }
}
